package PlotPourri;

import Jama.Matrix;
import PlotPourri.Database.DatabaseKepler;
import PlotPourri.Database.StarDatabase;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class PCA {

    static int order;
    static BandName band;
    static int fourierThreshold = 2;
    private String starDatabaseLocation;
    
    public PCA(int ordr, BandName bn, String starDB) {
        order = ordr;
        band = bn;
        starDatabaseLocation = starDB;
    }

    public String printPCA() {
        //StarDatabase starDatabase = new DatabaseLMCi(new File("C:\\Users\\Earl\\Desktop\\PCA\\LMC\\OgleIII-F.dat")); // get stars
        StarDatabase starDatabase = new DatabaseKepler(new File(starDatabaseLocation)); // get stars
        Star[] stars = starDatabase.values().toArray(new Star[starDatabase.size()]); // list of stars from the database
        List<double[]> values = /*Lightcurves(stars);*/AkBks(stars);
        Matrix A = new Matrix(values.toArray(new double[values.size()][order * 2])); // Create Matrix A
        Matrix C = A.transpose().times(A); // get C = A' * A
        Matrix eigenvector = C.eig().getV(); // get the eigenvectors of the matrix A
        double[][] PrincipalComponents = A.times(eigenvector).getArray();
        String outputTotal = "";
        outer:
        for (int i = 0; i < stars.length; i++) {
            String out = stars[i].getPeriod() + "";
            for (int j = PrincipalComponents[i].length - 1; j >= 0; j--) {
                if (PrincipalComponents[i][j] == 0) continue outer;
                out += " " + PrincipalComponents[i][j];
            }
            outputTotal += out;
            System.out.println(out);
        }
        return outputTotal;
        //for (double d : C.eig().getRealEigenvalues()) System.out.println(d);
    }

    static List<double[]> AkBks(Star[] stars) {
        List<double[]> AkBks = new ArrayList<double[]>(); // make list of Ak's and Bk's for all stars
        for (int i = 0; i < stars.length; i++) AkBks.add(stars[i].AkBk(order, band, fourierThreshold)); // grab the Ak's and Bk's from each star and put them into the list
        return AkBks;
    }

    static List<double[]> Lightcurves(Star[] stars) {
        List<double[]> lcs = new ArrayList<double[]>();
        for (int i = 0; i < stars.length; i++) {
            double[] magnitudes = new double[100];
            int j = 0;
            Observation ob = stars[i].getBand(band).get(0);
            double[] coefficients = ob.getCoefficients(order);
            for (double[] magnitude : ob.getShiftedData(coefficients, order, magnitudes.length - 1))
                magnitudes[j++] = magnitude[1] - coefficients[0];
            lcs.add(magnitudes);
        }
        return lcs;
    }
}
